#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __LNB_ALLOC__
#define __LNB_ALLOC__

#include <iostream>
#include <new>
#include <cstddef>
#include <climits>
#include <cstdlib>
namespace lnb
{
	template<class T>
	T* _allocate(ptrdiff_t size, T*)
	{
		std::set_new_handler(0);
		T* tmp = (T*)operator new((size_t)(size * sizeof(T)));
		if (tmp == 0)
		{
			std::cerr << "out of memory" <<std::endl;
			exit(1);
		}
		return tmp;
	}

	template<class T>
	void _deallocate(T* buffer)
	{
		operator delete(buffer);
	}

	template<class T1, class T2>
	void _construct(T1* p, const T2& value)
	{
		new(p)T1(value);
	}

	template<class T>
	void _destroy(T* ptr)
	{
		ptr->~T();
	}

	template<class T>
	class allocator
	{
	public:
		typedef T value_type;
		typedef T* pointer;
		typedef const T* const_pointer;
		typedef T& reference;
		typedef const T& const_reference;
		typedef size_t size_type;
		typedef ptrdiff_t difference_type;

		template<class U>
		struct rebind
		{
			typedef allocator<U> other;
		};

		pointer allocate(size_type n, void* hint = 0)
		{
			return lnb::_allocate(n, (pointer*)0);
		}

		void deallocate(pointer* buffer, size_type n)
		{
			lnb::_deallocate(buffer);
		}

		void construct(pointer p, const T& value)
		{
			lnb::_construct(p, value);
		}

		void destroy(pointer p)
		{
			lnb::_destroy(p);
		}

		pointer address(reference x)
		{
			return (pointer)&x;
		}

		const_pointer const address(const_reference x)
		{
			return (const_pointer)&x;
		}

		size_type max_size()const
		{
			return size_type(UINT_MAX, sizeof(T));
		}

	};

}


#endif // lnb_alloc
